﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Xml.Serialization;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace ViewMaker.Core.Controls
{
    /// <summary>
    /// データグリッド コンボボックス列
    /// </summary>
    public class DataGridComboBoxColumnViewElement : DataGridColumnViewElement
    {
        public new class Properties : DataGridColumnViewElement.Properties
        {
            public const string ItemsSource = "ItemsSource";
            public const string SelectedValuePath = "SelectedValuePath";
            public const string DisplayMemberPath = "DisplayMemberPath";
        }

        /// <summary>
        /// 一覧用のデータソース
        /// </summary>
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "ItemsSourceList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        public string ItemsSource
        {
            get { return _itemSource; }
            set
            {
                _itemSource = value;
                OnPropertyChanged("ItemsSource");
                OnPropertyChanged("SelectedValueList");
            }
        }
        private string _itemSource;

        /// <summary>
        /// ItemsSourceで選択されたデータの値を示すプロパティのパス
        /// </summary>
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "SelectedValueList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        public string SelectedValuePath { get; set; }

        /// <summary>
        /// ItemsSourceの各アイテムの表示に利用するプロパティのパス
        /// </summary>
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "SelectedValueList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        public string DisplayMemberPath { get; set; }

        [XmlIgnore]
        [Browsable(false)]
        public ObservableCollection<string> ItemsSourceList
        {
            get { return this.Item.BindablePathList; }
        }

        [XmlIgnore]
        [Browsable(false)]
        public ObservableCollection<string> SelectedValueList
        {
            get
            {
                if (ItemsSource == null) return null;
                return this.Item.CreateChildBindablePath(ItemsSource);
            }
        }

        public DataGridComboBoxColumnViewElement()
        {
            ControlType = ViewControlType.DataGridComboBoxColumn;
        }

#if !SILVERLIGHT
        public override List<XamlNode> CreateXaml(XamlNode parent)
        {
            var list = new List<XamlNode>();
            var col = parent.CreateElement("DataGridComboBoxColumn");
            if (!string.IsNullOrEmpty(Item.BindPath))
            {

                if (SelectedValuePath != null)
                {
                    col.SetAttribute("SelectedValuePath", SelectedValuePath);
                    SetBindingAttribute(col, "SelectedValueBinding", Item.BindPath, Item.IsOneWay);
                }
                else
                {
                    SetBindingAttribute(col, "SelectedItemBinding", Item.BindPath, Item.IsOneWay);
                }
                if (DisplayMemberPath != null) col.SetAttribute("DisplayMemberPath", DisplayMemberPath);

            }
            if (ItemsSource != null)
            {
                AddGridComboBoxStyle(col, "DataGridComboBoxColumn.ElementStyle");
                AddGridComboBoxStyle(col, "DataGridComboBoxColumn.EditingElementStyle");
            }
            ApplyBaseProperty(col);
            list.Add(col);
            return list;
        }

        private void AddGridComboBoxStyle(XamlNode col, string type)
        {
            var eleStyle = col.AddElement(type);
            var style = eleStyle.AddElement("Style");
            style.SetAttribute("TargetType", "ComboBox");
            var setter = style.AddElement("Setter");
            setter.SetAttribute("Property", "ItemsSource");
            setter.SetAttribute("Value", "{Binding Path=" + ItemsSource + "}");
        }
#else
        const string controlTemplateResource = @"
    <Style TargetType=""ComboBox"" xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
        xmlns:sdk=""http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"">
        <Setter Property=""Template"">
            <Setter.Value>
                <ControlTemplate TargetType=""ComboBox"">
                    <sdk:Label IsHitTestVisible=""False"" {0}>
                        <ContentPresenter></ContentPresenter>
                    </sdk:Label>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>";

        public override List<XamlNode> CreateXaml(XamlNode parent)
        {
            var list = new List<XamlNode>();
            var col = parent.CreateElement("sdk", "http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk", "DataGridTemplateColumn");
            AddGridComboBoxStyle(col, "DataGridTemplateColumn.CellTemplate", false, !Item.Parent.GetControl<DataGridViewControl>().IsReadOnly  );
            AddGridComboBoxStyle(col, "DataGridTemplateColumn.CellEditingTemplate", true, true);
            ApplyBaseProperty(col);
            list.Add(col);
            return list;
        }

        private void AddGridComboBoxStyle(XamlNode col, string type, bool isTabStop, bool isHitTestVisible)
        {
            var eleStyle = col.CreateElement("sdk", "http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk", type);
            col.AppendChild(eleStyle);
            var style = eleStyle.AddElement("DataTemplate");
            var combo = style.AddElement("ComboBox");
            SetBindingAttribute(combo, "ItemsSource", ItemsSource, true);
            if (!isTabStop) combo.SetAttribute("IsTabStop", "False");
            if (!isHitTestVisible) combo.SetAttribute("IsHitTestVisible", "False");
            if (IsReadOnly) combo.SetAttribute("IsEnabled", "False");

            if (!string.IsNullOrEmpty(Item.BindPath))
            {
                if (SelectedValuePath != null)
                {
                    SetBindingAttribute(combo, "SelectedValue", Item.BindPath, Item.IsOneWay);
                    combo.SetAttribute("SelectedValuePath", SelectedValuePath);
                    if (DisplayMemberPath != null) combo.SetAttribute("DisplayMemberPath", DisplayMemberPath);
                }
                else
                {
                    SetBindingAttribute(combo, "SelectedItem", Item.BindPath, Item.IsOneWay);
                }
            }
        }

#endif
    }

}
